package com.thememaker.lockstyle.control;

import com.jfoenix.controls.JFXRadioButton;
import com.jfoenix.controls.JFXTabPane;
import com.thememaker.lockstyle.bean.ui.BaseView;
import com.thememaker.lockstyle.bean.ui.Group;
import com.thememaker.lockstyle.bean.ui.Image;
import com.thememaker.lockstyle.customview.EditItemHBox;
import com.thememaker.lockstyle.parsii.ExpressionUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

import java.nio.file.Path;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;

public class TimeGroupControl implements ILockscreenControl {
    private VBox vBox, timebox, datebox, weekbox, dateCenBox, timeCenBox, weekCenBox;
    private Boolean isAll = true;
    private JFXRadioButton radio1, radio2;
    private Map<String, String> nameMap = new HashMap<>();
    private Map<String, EditItemHBox> editItemHBoxMap = new HashMap<>();
    private Map<String, JFXRadioButton> jfxRadioButtonMap = new HashMap<>();
    private EditItemHBox pointx, pointy, spacepoint;
    private String[] dataList = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "dot"};
    private String[] timeList = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "dot"};
    private String[] weekList = new String[]{"1", "2", "3", "4", "5", "6", "7"};
    FontImageDialog fontImageDialog;

    @Override
    public Node initLockscreenControl(BaseView baseView, Path lockscreenPath, ExpressionUtils expressionUtils, Consumer<BaseView> consumer) {
        if (baseView == null) {
            LinkedHashMap<String, BaseView> groupView = new LinkedHashMap<>();
            Group group = new Group();
            group.setGroupViewMap(groupView);
            baseView = group;
            baseView.setName("time_grp");
        }
        Accordion accordion = new Accordion();
//        accordion.setPadding(new Insets(20));
        vBox = LayoutComponentUtils.getInstance().getControlView(1080, 1180);
        timebox = LayoutComponentUtils.getInstance().getControlView(1070, 880);
        datebox = LayoutComponentUtils.getInstance().getControlView(1070, 880);
        weekbox = LayoutComponentUtils.getInstance().getControlView(1070, 880);
        dateCenBox = getControlView();
        timeCenBox = getControlView();
        weekCenBox = getControlView();
        LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap = ((Group) baseView).getGroupViewMap();
        stringBaseViewLinkedHashMap.forEach((s, baseView1) -> nameMap.put(Optional.ofNullable(baseView1.getName()).orElse(s), s));
        BaseView finalBaseView = baseView;
        timebox.getChildren().addAll(LayoutComponentUtils.getInstance().getEditTitleHbox("时间编辑:", (editButton, saveButton) -> {
            disable(true, "hour,minute", 0);
            disable(true, "dot_hour", 1);
            disable(false, "time_1,time_2", 2);
            editButton.setVisible(false);
            saveButton.setVisible(true);
            addFieldEvent("hour,dot_hour,minute", stringBaseViewLinkedHashMap);
            checkEdit("hour,dot_hour,minute");
        }, (editButton, saveButton) -> {
            disable(false, "hour,minute", 0);
            disable(false, "dot_hour", 1);
            disable(true, "time_1,time_2", 2);
            editButton.setVisible(true);
            saveButton.setVisible(false);
            setCenBox(stringBaseViewLinkedHashMap, "小       时：,时分分隔：,分       钟：", "hour,dot_hour,minute");
            consumer.accept(finalBaseView);
        }), getUnlockDirectionNode("time"));
        timeCenBox.getChildren().addAll(getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "小       时：", "hour", 0), getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "时分分隔：", "dot_hour", 1), getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "分       钟：", "minute", 0));
        /*时间图片展示*/
        getRadiuBtn("hour,dot_hour,minute,time");
        timebox.getChildren().addAll(timeCenBox,getEidtPane(consumer,lockscreenPath,finalBaseView,"time","0;1;2;3;4;5;6;7;8;9;:","time/time.png",timeList,"160","240"));
        /*年月日编辑*/
        datebox.getChildren().addAll(LayoutComponentUtils.getInstance().getEditTitleHbox("年月日编辑:", (editButton, saveButton) -> {
            disable(true, "year,month,date", 0);
            disable(true, "dot_year,dot_data", 1);
            disable(false, "date_1,date_2", 2);
            editButton.setVisible(false);
            saveButton.setVisible(true);
            addFieldEvent("year,dot_year,month,dot_data,date", stringBaseViewLinkedHashMap);
            checkEdit("year,dot_year,month,dot_data,date");
        }, (editButton, saveButton) -> {
            disable(false, "year,month,date", 0);
            disable(false, "dot_year,dot_data", 1);
            disable(true, "date_1,date_2", 2);
            editButton.setVisible(true);
            saveButton.setVisible(false);
            setCenBox(stringBaseViewLinkedHashMap, "年       份：,年月分隔：,月       份：,月日分隔：,日       期：", "year,dot_year,month,dot_data,date");
            consumer.accept(finalBaseView);
        }), getUnlockDirectionNode("date"));
        dateCenBox.getChildren().addAll(getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "年       份：", "year", 0), getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "年月分隔：", "dot_year", 1), getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "月       份：", "month", 0), getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "月日分隔：", "dot_data", 1), getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "日       期：", "date", 0));
        getRadiuBtn("year,dot_year,month,dot_data,date,date");
        datebox.getChildren().addAll(dateCenBox,getEidtPane(consumer,lockscreenPath,finalBaseView,"data","0;1;2;3;4;5;6;7;8;9;:","date/date.png",dataList,"50","80"));
        /*星期编辑*/
        weekbox.getChildren().addAll(LayoutComponentUtils.getInstance().getEditTitleHbox("星期编辑:", (editButton, saveButton) -> {
            disable(true, "week", 1);
            disable(false, "week", 2);
            editButton.setVisible(false);
            saveButton.setVisible(true);
        }, (editButton, saveButton) -> {
            disable(false, "week", 1);
            disable(true, "week", 2);
            editButton.setVisible(true);
            saveButton.setVisible(false);
            setAllpoint(stringBaseViewLinkedHashMap, "week", 1);
            consumer.accept(finalBaseView);
        }));
        weekbox.getChildren().addAll(getCoordinate(stringBaseViewLinkedHashMap, expressionUtils, "星       期：", "week", 1), getEidtPane(consumer,lockscreenPath,finalBaseView,"week","周一;周二;周三;周四;周五;周六;周日","week/week.png",weekList,"200","80"));
        TitledPane timePane = getTitlePane("  时间部分", timebox);
        accordion.getPanes().addAll(timePane, getTitlePane("  日期部分", datebox), getTitlePane("  星期部分", weekbox));
        accordion.setExpandedPane(timePane);
        accordion.setPadding(new Insets(15, -20, 0, 0));
        accordion.setMinSize(1070, 460);
        accordion.setMaxSize(1070, 1080);
        vBox.getChildren().add(accordion);
        return vBox;
    }

    @Override
    public Node getCacheLockscreenControl() {
        return null;
    }

    @Override
    public void updateView() {

    }

    public JFXTabPane getEidtPane(Consumer<BaseView> consumer, Path lockscreenPath, BaseView baseView, String type, String text, String imgSrc, String[] list, String w, String h){
        JFXTabPane tabPane = new JFXTabPane();
//        tabPane.setId("");
//        tabPane.getStyleClass().addAll("jfx-tab-pane");
        tabPane.setPadding(new Insets(10));
        Tab tab = new Tab();
        Tab tab1 = new Tab();

        tab.setText("图片替换");
        tab1.setText("字体生成");
        tab.setContent(LayoutComponentUtils.getInstance().getImageListPane(lockscreenPath.toString(), imgSrc, list, path -> consumer.accept(baseView)));
        tab1.setContent(new FontImageDialog().getVbox(text,type,w,h));
        tabPane.getTabs().addAll(tab,tab1);
        return tabPane;
    }

    private void getRadiuBtn(String type) {
        String[] types = type.split(",");
        jfxRadioButtonMap.get(types[types.length - 1] + "_2").selectedProperty().addListener((obj, oldValue, newValue) -> {
            if (newValue) {
                isAll = false;
                checkEdit(type);
            }
        });
        jfxRadioButtonMap.get(types[types.length - 1] + "_1").selectedProperty().addListener((obj, oldValue, newValue) -> {
            if (newValue) {
                isAll = true;
                checkEdit(type);
            }
        });
    }

    public void checkEdit(String type){
        String[] types = type.split(",");
        if(isAll){
            for (int i = 1; i < types.length; i++) {
                editItemHBoxMap.get(types[i] + "_y").setEditable(true);
            }
        }else {
            for (int i = 1; i < types.length; i++) {
                editItemHBoxMap.get(types[i] + "_y").setEditable(false);
            }
        }

    }

    private void setCenBox(LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap, String name, String type) {
        String[] strs = name.split(",");
        String[] types = type.split(",");
        if (isAll) {
            for (int i = 0; i < strs.length; i++) {
                String[] typenum = types[i].split("_");
                if (typenum.length > 1) {
                    setAllpoint(stringBaseViewLinkedHashMap, types[i], 1);
                } else {
                    setAllpoint(stringBaseViewLinkedHashMap, types[i], 0);
                }
            }
        } else {
            setOnceAllPoint(stringBaseViewLinkedHashMap, type);
        }
    }

    public void addFieldEvent(String type, LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap) {
        String[] types = type.split(",");
        editItemHBoxMap.get(types[0] + "_y").getTextField().textProperty().addListener(event -> {
            System.out.println(types[0]);
            if (!isAll) {
                setOnceAllPoint(stringBaseViewLinkedHashMap, type);
            }
        });
    }

    private Node getUnlockDirectionNode(String type) {
        HBox hBox = new HBox();
        ToggleGroup toggleGroup = new ToggleGroup();
        radio1 = LayoutComponentUtils.getInstance().getControlRadioButton("自定义位置 ", 100, toggleGroup, true);
        radio2 = LayoutComponentUtils.getInstance().getControlRadioButton("Y轴联动 ", 100, toggleGroup, false);
        jfxRadioButtonMap.put(type + "_1", radio1);
        jfxRadioButtonMap.put(type + "_2", radio2);
        disable(true, type + "_1" + "," + type + "_2", 2);
        Label label = new Label("   联动选择:    ");
        label.setStyle("-fx-text-fill: #6E8BA9");
        hBox.getChildren().addAll(label, radio1, radio2);
        return hBox;
    }

    public TitledPane getTitlePane(String title, VBox vBox) {
        TitledPane titledPane = new TitledPane(title, vBox);
        titledPane.setId("diy-center_titled_pane");
        titledPane.setStyle("-fx-text-fill: #716A94");
        return titledPane;
    }

    public void setOnceAllPoint(LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap, String timetype) {
        String[] strs = timetype.split(",");
        setAllpoint(stringBaseViewLinkedHashMap, strs[0], 0);
        BaseView baseView;
        baseView = stringBaseViewLinkedHashMap.get(nameMap.get(strs[0] + "_0"));
        for (int i = 1; i < strs.length; i++) {
            setotherPoint(stringBaseViewLinkedHashMap, baseView.getY(), strs[i]);
        }
    }

    public void setotherPoint(LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap, String y, String timetype) {
        String[] typenum = timetype.split("_");
        BaseView baseView;
        if (typenum.length > 1) {
            baseView = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype)).orElse("default"));
            if (baseView != null) {
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        baseView.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        baseView.setY(y);
                        editItem.setValue(y);
                    }
                });
            } else {
                Image bas = new Image();
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        bas.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        bas.setY(y);
                        editItem.setValue(y);
                    }
                });
                bas.setName(timetype);
                bas.setSrc(getSrc(timetype));
                bas.setSrcid(getSrcid(timetype));
                stringBaseViewLinkedHashMap.put(timetype, bas);
            }
        } else {
            baseView = stringBaseViewLinkedHashMap.get(nameMap.get(timetype + "_0"));
            int j = 1;
            if (timetype.equals("year")) {
                j = 3;
            }
            if (baseView != null) {
                int finalJ1 = j;
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        baseView.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        baseView.setY(y);
                        editItem.setValue(y);
                    }
                });
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_space")) {
                        for (int i = 1; i <= finalJ1; i++) {
                            BaseView base = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype + "_" + i)).orElse("default"));
                            if (base != null) {
                                double x = Double.parseDouble(baseView.getX()) + Double.parseDouble(editItem.getEditValue()) * i;
                                int newx = (int) x;
                                base.setX(newx + "");
                                base.setY(y);
                            }
                        }
                    }
                });
            } else {
                Image bas = new Image();
                int finalJ = j;
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        bas.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        bas.setY(editItem.getEditValue());
                        editItem.setValue(y);
                    } else if (s.equals(timetype + "_space")) {
                        for (int i = 0; i <= finalJ; i++) {
                            Image base = new Image();
                            double x = Double.parseDouble(bas.getX()) + Double.parseDouble(editItem.getEditValue()) * i;
                            int newx = (int) x;
                            base.setX(newx + "");
                            base.setY(y);
                            base.setName(timetype + "_" + i);
                            base.setSrc(getSrc(timetype));
                            base.setSrcid(getSrcid(timetype + "_" + i));
                            stringBaseViewLinkedHashMap.put(timetype + "_" + i, base);
                        }
                    }
                });
            }
        }
    }

    public void setAllpoint(LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap, String timetype, int type) {
        BaseView baseView;
        int j = 1;
        if (timetype.equals("year")) {
            j = 3;
        }
        if (type == 0) {
            baseView = stringBaseViewLinkedHashMap.get(nameMap.get(timetype + "_0"));
            if (baseView != null) {
                int finalJ1 = j;
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        baseView.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        baseView.setY(editItem.getEditValue());
                    }
                });
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_space")) {
                        for (int i = 1; i <= finalJ1; i++) {
                            BaseView base = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype + "_" + i)).orElse("default"));
                            if (base != null) {
                                double x = Double.parseDouble(baseView.getX()) + Double.parseDouble(editItem.getEditValue()) * i;
                                int newx = (int) x;
                                base.setX(newx + "");
                                base.setY(baseView.getY());
                            }
                        }
                    }
                });
            } else {
                Image bas = new Image();
                int finalJ = j;
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        bas.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        bas.setY(editItem.getEditValue());
                    } else if (s.equals(timetype + "_space")) {
                        for (int i = 0; i <= finalJ; i++) {
                            Image base = new Image();
                            double x = Double.parseDouble(bas.getX()) + Double.parseDouble(editItem.getEditValue()) * i;
                            int newx = (int) x;
                            base.setX(newx + "");
                            base.setY(bas.getY());
                            base.setName(timetype + "_" + i);
                            base.setSrc(getSrc(timetype));
                            base.setSrcid(getSrcid(timetype + "_" + i));
                            stringBaseViewLinkedHashMap.put(timetype + "_" + i, base);
                        }
                    }
                });
            }
        } else {
            baseView = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype)).orElse("default"));
            if (baseView != null) {
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        baseView.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        baseView.setY(editItem.getEditValue());
                    }
                });
            } else {
                Image bas = new Image();
                editItemHBoxMap.forEach((s, editItem) -> {
                    if (s.equals(timetype + "_x")) {
                        bas.setX(editItem.getEditValue());
                    } else if (s.equals(timetype + "_y")) {
                        bas.setY(editItem.getEditValue());
                    }
                });
                bas.setName(timetype);
                bas.setSrc(getSrc(timetype));
                bas.setSrcid(getSrcid(timetype));
                stringBaseViewLinkedHashMap.put(timetype, bas);
            }
        }
    }

    public VBox getCoordinate(LinkedHashMap<String, BaseView> stringBaseViewLinkedHashMap, ExpressionUtils expressionUtils, String name, String timetype, int type) {
        VBox vBox1 = new VBox();
        BaseView baseView;
        BaseView baseView2 = null;
        if (type == 0) {
            baseView = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype + "_0")).orElse("default"));
            baseView2 = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype + "_1")).orElse("default"));
        } else {
            baseView = stringBaseViewLinkedHashMap.get(Optional.ofNullable(nameMap.get(timetype)).orElse("default"));
        }
        Label label = new Label(name);
        if (baseView2 != null) {
            if (baseView != null) {
                double space = expressionUtils.parseExpr(Optional.ofNullable(baseView2.getX()).orElse("0")) - expressionUtils.parseExpr(Optional.ofNullable(baseView.getX()).orElse("0"));
                vBox1.getChildren().add(getTimeBox(label,
                        (int) expressionUtils.parseExpr(Optional.ofNullable(baseView.getX()).orElse("")) + "",
                        (int) expressionUtils.parseExpr(Optional.ofNullable(baseView.getY()).orElse("")) + "",
                        (int) space + "", timetype, type));
            } else {
                vBox1.getChildren().add(getTimeBox(label, "", "", "", timetype, type));
            }
        } else {
            if (baseView != null) {
                vBox1.getChildren().add(getTimeBox(label,
                        (int) expressionUtils.parseExpr(Optional.ofNullable(baseView.getX()).orElse("")) + "",
                        (int) expressionUtils.parseExpr(Optional.ofNullable(baseView.getY()).orElse("")) + "",
                        null, timetype, type));
            } else {
                vBox1.getChildren().add(getTimeBox(label, "", "", "", timetype, type));
            }
        }
        return vBox1;
    }

    public VBox getTimeBox(Label time, String x, String y, String space, String timetype, int type) {
        pointx = EditItemHBox.initEditItem("  X坐标 ", x, 150);
        pointy = EditItemHBox.initEditItem("  y坐标 ", y, 150);
        VBox vBox = new VBox();
        HBox hbox = new HBox();
        hbox.setAlignment(Pos.CENTER_LEFT);
        time.setStyle("-fx-text-fill: #6E8BA9");
        editItemHBoxMap.put(timetype + "_x", pointx);
        editItemHBoxMap.put(timetype + "_y", pointy);
        if (type == 0) {
            hbox.getChildren().addAll(time);
            spacepoint = EditItemHBox.initEditItem("  间隔 ", space, 150);
            editItemHBoxMap.put(timetype + "_space", spacepoint);
            hbox.getChildren().addAll(pointx, pointy, spacepoint);
        } else {
            hbox.getChildren().addAll(time);
            hbox.getChildren().addAll(pointx, pointy);
        }
        disable(false, timetype, type);
        vBox.getChildren().add(hbox);
        return vBox;
    }

    private String getSrcid(String srcid) {
        Map<String, String> map = new LinkedHashMap<String, String>() {{
            put("year_0", "#year/1000");
            put("year_1", "#year%1000/100");
            put("year_2", "#year%100/10");
            put("year_3", "(#year%10");
            put("month_0", "(#month+1)/10");
            put("month_1", "(#month+1)%10");
            put("date_0", "#date/10");
            put("date_1", "#date%10");
            put("week", "#day_of_week");
            put("hour_0", "ifelse(#time_format,#hour24/10,#hour12/10)");
            put("hour_1", "ifelse(#time_format,#hour24%10,#hour12%10)");
            put("minute_0", "#minute/10");
            put("minute_1", "#minute%10");
        }};
        return getSrcidByModelMap(map, srcid);
    }

    public String getSrc(String src) {
        Map<String, String> map = new LinkedHashMap<String, String>() {{
            put("year", "date/date.png");
            put("month", "date/date.png");
            put("dot_year", "date/date_dot.png");
            put("dot_data", "date/date_dot.png");
            put("week", "week/week.png");
            put("dot_hour", "time/time_dot.png");
        }};
        return getSrcidByModelMap(map, src);
    }

    public void disable(Boolean dis, String timetype, int type) {
        String[] strs = timetype.split(",");
        for (int i = 0; i < strs.length; i++) {
            if (type == 0) {
                editItemHBoxMap.get(strs[i] + "_x").setEditable(dis);
                editItemHBoxMap.get(strs[i] + "_y").setEditable(dis);
                editItemHBoxMap.get(strs[i] + "_space").setEditable(dis);
            } else if (type == 1) {
                editItemHBoxMap.get(strs[i] + "_x").setEditable(dis);
                editItemHBoxMap.get(strs[i] + "_y").setEditable(dis);
            } else {
                jfxRadioButtonMap.get(strs[i]).setDisable(dis);
            }
        }


    }

    public static String getSrcidByModelMap(Map<String, String> modelMap, String srcid) {
        return srcid == null ? null : modelMap.keySet()
                .stream()
                .filter(key -> key.contains(srcid))
                .map(modelMap::get)
                .findFirst().orElse(null);
    }

    public VBox getControlView() {
        VBox vBox = new VBox();
        vBox.getStylesheets().add("style/lockstylemain.css");
        vBox.setPadding(new Insets(10, 10, 10, 10));
        vBox.setSpacing(10);
        vBox.setAlignment(Pos.TOP_LEFT);
        vBox.setStyle("-fx-background-color: white;");
        vBox.getStyleClass().addAll("custom-color-dialog");
        return vBox;
    }
}
